package pl.edu.pk.mech.kkbus.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;

import org.apache.commons.codec.digest.DigestUtils;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import pl.edu.pk.mech.kkbus.component.MyEntityManagerFactory;
import pl.edu.pk.mech.kkbus.entities.*;

@Controller
@RequestMapping("/data")
public class DataGeneratorController {
    
    // Fuck DRY!
    
    EntityManagerFactory emf = MyEntityManagerFactory.get();
    
    @RequestMapping(value = "/account/admin", method = RequestMethod.GET)
    public @ResponseBody String generateAdmin() {
        EntityManager em = null;
        try {
            em = emf.createEntityManager();

            User user = new User();
            user.setName("Jan");
            user.setSurname("Kowalski");
            user.setBirthday(new Date());
            user.setEmail("admin@kkbus.pl");
            user.setPassword(DigestUtils.md5Hex("qwerty123"));
            user.setHash(null);
            user.setPhone("888999777");
            user.setPoints(1000);
            user.setEnabled(true);
            Set<User.Role> roles = new LinkedHashSet<User.Role>();
            roles.add(User.Role.USER);
            roles.add(User.Role.ADMIN);
            user.setRoles(roles);
            List<HistoryLog> historyLogs = new ArrayList<HistoryLog>();
            historyLogs.add(new HistoryLog(new Date()));
            user.setHistoryLogs(historyLogs);

            em.persist(user);
        } catch(Exception e) {
            e.printStackTrace();
            return "ERROR";
        } finally {
            if (em != null)
                em.close();
        }
        
        return "GENERATED";
    }
    
    @RequestMapping(value = "/account/worker", method = RequestMethod.GET)
    public @ResponseBody String generateWorker() {
        EntityManager em = null;
        try {
            em = emf.createEntityManager();

            // Worker
            User user = new User();
            user.setName("Adam");
            user.setSurname("Nowak");
            user.setBirthday(new Date());
            user.setEmail("worker@kkbus.pl");
            user.setPassword(DigestUtils.md5Hex("qwerty123"));
            user.setHash(null);
            user.setPhone("888999777");
            user.setPoints(1000);
            user.setEnabled(true);                    
            Set<User.Role> roles = new LinkedHashSet<User.Role>();
            roles.add(User.Role.USER);
            roles.add(User.Role.WORKER);
            user.setRoles(roles);

            em.persist(user);
        } catch(Exception e) {
            e.printStackTrace();
            return "ERROR";
        } finally {
            if (em != null)
                em.close();
        }
        
        return "GENERATED";
    }
    
    @RequestMapping(value = "/account/user", method = RequestMethod.GET)
    public @ResponseBody String generateUser() {
        EntityManager em = null;
        try {
            em = emf.createEntityManager();

            // User
            User user = new User();
            user.setName("Ola");
            user.setSurname("Tyl");
            user.setBirthday(new Date());
            user.setEmail("user@kkbus.pl");
            user.setPassword(DigestUtils.md5Hex("qwerty123"));
            user.setHash(null);
            user.setPhone("888999777");
            user.setPoints(1000);
            user.setEnabled(true);
            Set<User.Role> roles = new LinkedHashSet<User.Role>();
            roles.add(User.Role.USER);
            user.setRoles(roles);
            em.persist(user);

            em.persist(user);
        } catch(Exception e) {
            e.printStackTrace();
            return "ERROR";
        } finally {
            if (em != null)
                em.close();
        }
        
        return "GENERATED";
    }
    
    @RequestMapping(value = "/award", method = RequestMethod.GET)
    public @ResponseBody String generateAward() {
        EntityManager em = null;
            try {
                em = emf.createEntityManager();
                // Award
                Award award = new Award("Lorem ipsum", "Etiam vulputate gravida imperdiet. In porttitor bibendum magna.", 250, 10);
                em.persist(award);
                
            } catch(Exception e) {
                e.printStackTrace();
                return "ERROR";
            } finally {
                if (em != null)
                    em.close();
            }
        
        return "GENERATED";
    }
    
    @RequestMapping(value = "/news", method = RequestMethod.GET)
    public @ResponseBody String generateNews() {
        EntityManager em = null;
            try {
                em = emf.createEntityManager();
                // News
                News news = new News("Lorem ipsum", "Etiam vulputate gravida imperdiet. In porttitor bibendum magna.", new Date());
                em.persist(news);
                
            } catch(Exception e) {
                e.printStackTrace();
                return "ERROR";
            } finally {
                if (em != null)
                    em.close();
            }
        
        return "GENERATED";
    }
    
    @RequestMapping(value = "/exchange/user/{userId}/award/{awardId}", method = RequestMethod.GET)
    public @ResponseBody String generateExchange(@PathVariable(value = "userId") long userId,
            @PathVariable(value = "awardId") long awardId) {
         EntityManager em = null;
        try {
            em = emf.createEntityManager();
            Exchange exchange = new Exchange();
            exchange.setAwardId(awardId);
            exchange.setUserId(userId);
            exchange.setHash(DigestUtils.md5Hex(String.valueOf(new Date()) + "pHe1Ux7kJA"));
            
            em.persist(exchange);
        } catch(Exception e) {
            e.printStackTrace();
            return "ERROR";
        } finally {
            if (em != null)
                em.close();
        }
        
        return "GENERATED";
    }
    
    @RequestMapping(value = "/busstops/krakow", method = RequestMethod.GET)
    public @ResponseBody String generateBusStopKrakow() {
        EntityManager em = null;
        try {
            
            em = emf.createEntityManager();
            EntityTransaction txn = em.getTransaction();
            txn.begin();
            
            try {
                // Kraków - Katowice
                BusStop busStop = new BusStop();
                List<DepartureTime> dt = new LinkedList<DepartureTime>();
                dt.add(new DepartureTime("8:00", "7 A", 0));
                dt.add(new DepartureTime("8:30", "7", 10));
                dt.add(new DepartureTime("9:00", "7 F", 20));    
                dt.add(new DepartureTime("9:30", "6", 30)); 
                busStop.setDepartureTimes(dt);
                busStop.setDirection(BusStop.Direction.KRAKOW_KATOWICE);
                busStop.setDistance(10);
                busStop.setName("Kraków RDA");
                busStop.setPrice(12);
                busStop.setSequence(0);
                em.persist(busStop);
                
                busStop = new BusStop();
                dt = new LinkedList<DepartureTime>();
                dt.add(new DepartureTime("8:30", "7 A", 0));
                dt.add(new DepartureTime("9:00", "7", 10));
                dt.add(new DepartureTime("9:30", "7 F", 20));  
                dt.add(new DepartureTime("10:00", "6", 30)); 
                busStop.setDepartureTimes(dt);
                busStop.setDirection(BusStop.Direction.KRAKOW_KATOWICE);
                busStop.setDistance(20);
                busStop.setName("Chrzanów");
                busStop.setPrice(13);
                busStop.setSequence(10);
                em.persist(busStop);
                
                busStop = new BusStop();
                dt = new LinkedList<DepartureTime>();
                dt.add(new DepartureTime("9:00", "7 A", 0));
                dt.add(new DepartureTime("9:30", "7", 10));
                dt.add(new DepartureTime("10:00", "7 F", 20));  
                dt.add(new DepartureTime("10:30", "6", 30)); 
                busStop.setDepartureTimes(dt);
                busStop.setDirection(BusStop.Direction.KRAKOW_KATOWICE);
                busStop.setDistance(30);
                busStop.setName("Katowice Górnośląska");
                busStop.setPrice(14);
                busStop.setSequence(20);
                em.persist(busStop);
                
                busStop = new BusStop();
                dt = new LinkedList<DepartureTime>();
                dt.add(new DepartureTime("9:30", "7 A", 0));
                dt.add(new DepartureTime("10:00", "7", 10));
                dt.add(new DepartureTime("10:30", "7 F", 20));  
                dt.add(new DepartureTime("11:00", "6", 30)); 
                busStop.setDepartureTimes(dt);
                busStop.setDirection(BusStop.Direction.KRAKOW_KATOWICE);
                busStop.setDistance(40);
                busStop.setName("Katowice Francuska (stacja BP)");
                busStop.setPrice(15);
                busStop.setSequence(30);
                em.persist(busStop);              

                txn.commit();
            } catch(Exception e) {
                e.printStackTrace();
            } finally {
                if (txn.isActive()) {
                    txn.rollback();
                }
            }
        } catch(Exception e) {
            e.printStackTrace();
            return "ERROR";
        } finally {
            if (em != null)
                em.close();
        }
        
        return "GENERATED";
    }
    
    @RequestMapping(value = "/busstops/katowice", method = RequestMethod.GET)
    public @ResponseBody String generateBusStopKatowice() {
        EntityManager em = null;
        try {
            
            em = emf.createEntityManager();
            EntityTransaction txn = em.getTransaction();
            txn.begin();
            
            try {
                // Katowice - Kraków
                BusStop busStop = new BusStop();
                List<DepartureTime> dt = new LinkedList<DepartureTime>();
                dt.add(new DepartureTime("8:00", "7 A", 0));
                dt.add(new DepartureTime("8:30", "7", 10));
                dt.add(new DepartureTime("9:00", "7 F", 20));    
                dt.add(new DepartureTime("9:30", "6", 30)); 
                busStop.setDepartureTimes(dt);
                busStop.setDirection(BusStop.Direction.KATOWICE_KRAKOW);
                busStop.setDistance(20);
                busStop.setName("Katowice Dw. PKP");
                busStop.setPrice(13);
                busStop.setSequence(0);
                em.persist(busStop);
                
                busStop = new BusStop();
                dt = new LinkedList<DepartureTime>();
                dt.add(new DepartureTime("8:30", "7 A", 0));
                dt.add(new DepartureTime("9:00", "7", 10));
                dt.add(new DepartureTime("9:30", "7 F", 20));    
                dt.add(new DepartureTime("10:00", "6", 30)); 
                busStop.setDepartureTimes(dt);
                busStop.setDirection(BusStop.Direction.KATOWICE_KRAKOW);
                busStop.setDistance(30);
                busStop.setName("Kraków Motel Krak");
                busStop.setPrice(14);
                busStop.setSequence(10);
                em.persist(busStop);
                
                busStop = new BusStop();
                dt = new LinkedList<DepartureTime>();
                dt.add(new DepartureTime("9:00", "7 A", 0));
                dt.add(new DepartureTime("9:30", "7", 10));
                dt.add(new DepartureTime("10:00", "7 F", 20));    
                dt.add(new DepartureTime("10:30", "6", 30)); 
                busStop.setDepartureTimes(dt);
                busStop.setDirection(BusStop.Direction.KATOWICE_KRAKOW);
                busStop.setDistance(40);
                busStop.setName("Kraków Czarnowiejska");
                busStop.setPrice(15);
                busStop.setSequence(20);
                em.persist(busStop);                

                txn.commit();
            } catch(Exception e) {
                e.printStackTrace();
            } finally {
                if (txn.isActive()) {
                    txn.rollback();
                }
            }
        } catch(Exception e) {
            e.printStackTrace();
            return "ERROR";
        } finally {
            if (em != null)
                em.close();
        }
        
        return "GENERATED";
    }
    
    @RequestMapping(value = "/bus", method = RequestMethod.GET)
    public @ResponseBody String generateBus() {
        EntityManager em = null;
            try {
                em = emf.createEntityManager();
                // Bus
                Bus bus = new Bus("Volkswagen Transporter", "Bardzo pakowany bus.",
                        26, "KR 0000", "Kraków koło PK", 2006);
                em.persist(bus);
                
            } catch(Exception e) {
                e.printStackTrace();
                return "ERROR";
            } finally {
                if (em != null)
                    em.close();
            }
        
        return "GENERATED";
    }
    
    @RequestMapping(value = "/bus/{id}/defect", method = RequestMethod.GET)
    public @ResponseBody String generateDefectForBus(@PathVariable long id) {
        EntityManager em = null;
        try {
            em = emf.createEntityManager();
            // Defect
            Defect d = new Defect("Urwane lusterko.", 50.90, new Date(), id);
            em.persist(d);
        } catch(Exception e) {
            e.printStackTrace();
            return "ERROR";
        } finally {
            if (em != null)
                em.close();
        }
        
        return "GENERATED";
    }
    
    @RequestMapping(value = "/bus/{id}/refueling", method = RequestMethod.GET)
    public @ResponseBody String generateRefuelingForBus(@PathVariable long id) {
        EntityManager em = null;
        try {
            em = emf.createEntityManager();
            Refueling r = new Refueling(40, 219.90, new Date(), id);
            em.persist(r);
        } catch(Exception e) {
            e.printStackTrace();
            return "ERROR";
        } finally {
            if (em != null)
                em.close();
        }
        
        return "GENERATED";
    }
    
    @RequestMapping(value = "/workplan/user/{id}/day/{day}", method = RequestMethod.GET)
    public @ResponseBody String generateWorkPlanForUser(@PathVariable long id,
        @PathVariable String day) {
        EntityManager em = null;
        try {
            em = emf.createEntityManager();
            WorkPlan wp = new WorkPlan("8:00", "16:00", WorkPlan.Day.valueOf(day), id);
            em.persist(wp);
        } catch(Exception e) {
            e.printStackTrace();
            return "ERROR";
        } finally {
            if (em != null)
                em.close();
        }
        
        return "GENERATED";
    }

}